package com.chinawlx.wlxteacher.network;


import android.util.Log;

import com.chinawlx.wlxteacher.R;
import com.chinawlx.wlxteacher.base.WLXApplication;
import com.chinawlx.wlxteacher.network.bean.WLXAboutFutrueStarBean;
import com.chinawlx.wlxteacher.network.bean.WLXCalendarBean;
import com.chinawlx.wlxteacher.network.bean.WLXClazzDynamicBean;
import com.chinawlx.wlxteacher.network.bean.WLXClazzHomeWorkBean;
import com.chinawlx.wlxteacher.network.bean.WLXClazzListBean;
import com.chinawlx.wlxteacher.network.bean.WLXCommentListBean;
import com.chinawlx.wlxteacher.network.bean.WLXCourseFinishedBean;
import com.chinawlx.wlxteacher.network.bean.WLXCourseManageBean;
import com.chinawlx.wlxteacher.network.bean.WLXGetCodeBean;
import com.chinawlx.wlxteacher.network.bean.WLXHomeWorkCommentBean;
import com.chinawlx.wlxteacher.network.bean.WLXHomeworkAddBean;
import com.chinawlx.wlxteacher.network.bean.WLXLogOffBean;
import com.chinawlx.wlxteacher.network.bean.WLXLoginBean;
import com.chinawlx.wlxteacher.network.bean.WLXRollCallBean;
import com.chinawlx.wlxteacher.network.bean.WLXScheduleChangeBean;
import com.chinawlx.wlxteacher.network.bean.WLXScheduleScoreBean;
import com.chinawlx.wlxteacher.network.bean.WLXSingleCourseBean;
import com.chinawlx.wlxteacher.network.bean.WLXStudentBean;
import com.chinawlx.wlxteacher.network.bean.WLXTimeLineBean;
import com.chinawlx.wlxteacher.network.bean.WLXUploadImagesBean;
import com.chinawlx.wlxteacher.network.bean.WLXUploadVideoBean;
import com.chinawlx.wlxteacher.utils.WLXConstant;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;


public class WLXHttpRxHelper {

    private Retrofit mRetrofit;
    private WLXRxService mMyService;

    /**
     * 读取本地证书文件-返回对象
     */
    public SSLSocketFactory getCertificates() {
        try {
            InputStream inputStream = WLXApplication.myApplication.getResources().openRawResource
                    (R.raw.https);
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null);
            int index = 0;
            String certificateAlias = Integer.toString(index++);
            keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate
                    (inputStream));

            try {
                if (inputStream != null) inputStream.close();
            } catch (IOException e) {
            }

            SSLContext sslContext = SSLContext.getInstance("TLS");

            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance
                    (TrustManagerFactory.getDefaultAlgorithm());

            trustManagerFactory.init(keyStore);
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    private WLXHttpRxHelper() {


        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);


        OkHttpClient okHttpClient = new OkHttpClient.Builder().sslSocketFactory(getCertificates()
        ).addInterceptor(logging).
                cookieJar(new CookieJar() {

                    @Override
                    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
                        if (WLXConstant.IS_ACTIVE == 0) {
                            WLXConstant.cookieStore = cookies;
                        }
                    }

                    @Override
                    public List<Cookie> loadForRequest(HttpUrl url) {
                        return WLXConstant.cookieStore;
                    }
                }).build();

        mRetrofit = new Retrofit.Builder().baseUrl(WLXConstant.BASE_URL).addConverterFactory
                (GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory
                .create()).client(okHttpClient).build();
        mMyService = mRetrofit.create(WLXRxService.class);
    }

    public static WLXHttpRxHelper getInstance() {
        return SingletonHolder.instance;
    }


    private static class SingletonHolder {
        private static final WLXHttpRxHelper instance = new WLXHttpRxHelper();
    }

    /**
     * 登陆页面获取验证码接口
     *
     * @param mobile
     * @param type_code
     * @param timestamp
     * @param sign
     * @param subscriber
     */
    public void getCode(String mobile, String type_code, String timestamp, String sign,
                        Subscriber<WLXGetCodeBean> subscriber) {
        mMyService.getCode(mobile, type_code, timestamp, sign).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 登陆接口
     *
     * @param code
     * @param mobile
     * @param timestamp
     * @param sign
     * @param subscriber
     */
    public void login(String code, String mobile, String timestamp, String sign,
                      Subscriber<WLXLoginBean> subscriber) {
        mMyService.login(mobile, code, timestamp, sign).subscribeOn(Schedulers.io()).observeOn
                (AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 获取班级列表接口
     *
     * @param paging_index
     * @param paging_size
     * @param subscriber
     */
//    public void getClazzList(String grade_id, String paging_index, String paging_size,
    public void getClazzList(String paging_index, String paging_size,
                             Subscriber<WLXClazzListBean> subscriber) {
        mMyService.getClazzList(paging_index, paging_size).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 课程管理接口
     *
     * @param grade_id
     * @param paging_index
     * @param paging_size
     * @param subscriber
     */
    public void getCourseManage(String grade_id, String paging_index, String paging_size,
                                Subscriber<WLXCourseManageBean> subscriber) {
        mMyService.getCourseManage(grade_id, paging_index, paging_size).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);

    }

    /**
     * 作业点评
     *
     * @param subscriber public void getHomeWorkComment(String homework_id, String content,
     *                   String content_code,
     *                   String duration,
     *                   String file, Subscriber<ResponseBody> subscriber) {
     *                   mMyService.getHomeWorkComment(homework_id, content, content_code,
     *                   duration, file)
     *                   .subscribeOn(Schedulers.io())
     *                   .observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
     *                   }
     */
    public void getCommentList(String grade_id, Subscriber<WLXCommentListBean>
            subscriber) {
        mMyService.getCommentList(grade_id)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 班级作业列表
     *
     * @param paging_index
     * @param paging_size
     * @param subscriber
     */
    public void getClassHomeWork(String grade_id, String paging_index, String paging_size,
                                 Subscriber<WLXClazzHomeWorkBean> subscriber) {
        mMyService.getClassHomeWork(grade_id, paging_index, paging_size).subscribeOn(Schedulers
                .io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }

    /**
     * 单个作业回复列表
     *
     * @param homework_id
     * @param subscriber
     */
    public void getHomeWorkComment(String homework_id, String s,
                                   Subscriber<WLXHomeWorkCommentBean> subscriber) {
        mMyService.getHomeWorkComment(homework_id, s).subscribeOn(Schedulers.io()).observeOn
                (AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 获取教师的全部学生列表
     *
     * @param subscriber
     */
    public void getStudentList(Subscriber<WLXStudentBean> subscriber) {
        mMyService.getStudentAllList().subscribeOn(Schedulers
                .io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 获取班级动态
     *
     * @param grade_id
     * @param paging_index
     * @param paging_size
     * @param subscriber
     */
    public void getClazzDynamic(String grade_id, String paging_index, String paging_size,
                                Subscriber<WLXClazzDynamicBean> subscriber) {
        mMyService.getClazzDynamic(grade_id, paging_index, paging_size)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 获取课次统计
     *
     * @param subscriber
     */
    public void getLessonStatistics(Subscriber<ResponseBody> subscriber) {
        mMyService.getLessonStatistics().subscribeOn(Schedulers
                .io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);

    }

    /**
     * 修改昵称和qq
     *
     * @param field_name
     * @param field_value
     * @param subscriber
     */
    public void changeNickNameAndQQ(String field_name, String field_value,
                                    Subscriber<ResponseBody> subscriber) {
        mMyService.changeNickNameAndQQ(field_name, field_value).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }

    /**
     * 教师添加评论页面
     *
     * @param homework_id  作业id
     * @param content      内容
     * @param content_code 内容编码
     * @param duration     时长,语音不需要
     * @param file         语音文件数据
     */
    public void teacherCommentAdd(String homework_id, String content, String content_code, String
            duration, File file, Subscriber<WLXGetCodeBean> responseBody) {
        RequestBody homeworkBody =
                RequestBody.create(
                        MediaType.parse("multipart/form-data"), homework_id);
        RequestBody contentBody =
                RequestBody.create(
                        MediaType.parse("multipart/form-data"), content);
        RequestBody contentCodeBody =
                RequestBody.create(
                        MediaType.parse("multipart/form-data"), content_code);

        if ("text".equals(content_code)) {
//            文本
            mMyService.teacherCommentAddText(homework_id, content, content_code)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(responseBody);
        } else if ("audio".equals(content_code)) {
            //音频
            RequestBody durationBody =
                    RequestBody.create(MediaType.parse("multipart/form-data"), duration);

            RequestBody requestFile =
                    RequestBody.create(MediaType.parse("multipart/form-data"), file);
            CountingRequestBody countingRequestBody = new CountingRequestBody(requestFile, new
                    CountingRequestBody.Listener() {
                        @Override
                        public void onRequestProgress(long bytesWritten, long contentLength) {
                            Log.e("byron", contentLength + ":" + bytesWritten);
                        }
                    });
            MultipartBody.Part body =
                    MultipartBody.Part.createFormData("file", file.getName(), countingRequestBody);
            mMyService.teacherCommentAdd(homeworkBody, contentBody, contentCodeBody,
                    durationBody, body)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(responseBody);
        }

    }

    /**
     * 登出账号
     *
     * @param subscriber
     */
    public void logoff(Subscriber<WLXLogOffBean> subscriber) {
        mMyService.logoff().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()
        ).subscribe(subscriber);
    }

    /**
     * 关于未来星
     *
     * @param subscriber
     */
    public void aboutFutureStar(Subscriber<WLXAboutFutrueStarBean> subscriber) {
        mMyService.aboutFutureStar().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers
                .mainThread()).subscribe(subscriber);
    }

    /**
     * 点名,student_ids为空时
     *
     * @param grade_id
     * @param schedule_id
     * @param subscriber
     */
    public void callRollIdsNull(String grade_id, String schedule_id, String student_ids,
                                Subscriber<WLXRollCallBean> subscriber) {
        mMyService.callRollIdsNull(grade_id, schedule_id, student_ids).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }


    /**
     * 点名,student_ids不为空时
     *
     * @param grade_id
     * @param schedule_id
     * @param subscriber
     */
    public void callRollIdsNotNull(String grade_id, String schedule_id, String student_ids,
                                   Subscriber<WLXRollCallBean> subscriber) {
        mMyService.callRollIdsNotNull(grade_id, schedule_id, student_ids).subscribeOn(Schedulers
                .io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 上传教师头像
     *
     * @param file       要上传的文件
     * @param subscriber
     */
    public void uploadTeacherAvatar(File file, Subscriber<WLXGetCodeBean> subscriber) {
        RequestBody requestFile =
                RequestBody.create(MediaType.parse("multipart/form-data"), file);
        CountingRequestBody countingRequestBody = new CountingRequestBody(requestFile, new
                CountingRequestBody.Listener() {
                    @Override
                    public void onRequestProgress(long bytesWritten, long contentLength) {
                        Log.e("byron", contentLength + ":" + bytesWritten);
                    }
                });
        MultipartBody.Part body =
                MultipartBody.Part.createFormData("file", file.getName(), countingRequestBody);
        mMyService.uploadTeacherAvatar(body).subscribeOn(Schedulers
                .io()).observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }


    /**
     * 课程内容-图片举报
     */
    public void report(String resource_id, String resource_code, String content,
                       Subscriber<WLXGetCodeBean> subscriber) {
        mMyService.reportCreate(resource_id, resource_code, content).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }


    /**
     * 班级调课
     *
     * @param grade_id       班级ID
     * @param schedule_id    课程表ID
     * @param reason_code    原因编码
     * @param new_start_date 开始时间
     * @param new_end_date   结束时间
     */
    public void adjustLesson(String grade_id, String schedule_id, String reason_code, String
            new_start_date, String new_end_date, Subscriber<WLXGetCodeBean> subscriber) {
        mMyService.adjustLesson(grade_id, schedule_id, reason_code, new_start_date, new_end_date)
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe
                (subscriber);
    }


    /**
     * 获取学生课程表列表(日历数据)
     */
    public void schedule(String min_date, String max_date,
                         Subscriber<WLXCalendarBean> subscriber) {
        mMyService.schedule(min_date, max_date).subscribeOn(Schedulers.io
                ()).observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }


    /**
     * 主界面-时间线
     */
    public void timeLine(String student_id, String grade_id, int paging_index, int paging_size,
                         Subscriber<WLXTimeLineBean> subscriber) {
        mMyService.timeLine(student_id, grade_id, paging_index, paging_size).subscribeOn
                (Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }


    /**
     * 学生加课
     *
     * @param grade_id   班级ID
     * @param student_id 学生ID
     * @param week       星期几（1:星期一，2:星期二...7：星期天）
     * @param start_time 开始时间（12:00:00）
     * @param end_time
     * @param start_date 开始日期（2016-04-01）
     * @param end_date
     * @param subscriber
     */
    public void scheduleAddStudent(String grade_id, String student_id, String week, String
            start_time, String end_time,
                                   String start_date, String end_date,
                                   Subscriber<WLXGetCodeBean> subscriber) {
        mMyService.scheduleChangeAddStudent(grade_id, student_id, week, start_time, end_time,
                start_date, end_date)
                .subscribeOn
                        (Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe
                (subscriber);
    }


    /**
     * 老师请假接口
     *
     * @param grade_id    班级ID
     * @param schedule_id 课程表ID
     * @param reason_code 请假原因代码
     * @param subscriber
     */
    public void teacherLeave(String grade_id, String schedule_id, String reason_code,
                             Subscriber<WLXGetCodeBean> subscriber) {
        mMyService.teacherLeave(grade_id, schedule_id, reason_code)
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe
                (subscriber);
    }

    /**
     * 班级停课
     *
     * @param grade_id    班级ID
     * @param reason_code 原因
     * @param start_date  开始
     * @param end_date    结束日期（格式：2016-05-01）
     * @param subscriber
     */
    public void scheduleStopGrade(String grade_id,
                                  String reason_code, String start_date, String end_date,
                                  Subscriber<WLXGetCodeBean> subscriber) {
        mMyService.scheduleStopGrade(grade_id, reason_code, start_date, end_date).subscribeOn
                (Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe
                (subscriber);
    }

    /**
     * 某个学生停课
     *
     * @param grade_id    班级ID
     * @param student_id  学生ID
     * @param reason_code 原因编码
     * @param start_date  开始时间
     * @param end_date    结束时间
     * @param subscriber
     */
    public void scheduleStopStudent(String grade_id, String student_id,
                                    String reason_code, String start_date, String end_date,
                                    Subscriber<WLXGetCodeBean> subscriber) {
        mMyService.scheduleStopStudent(grade_id, student_id, reason_code, start_date, end_date)
                .subscribeOn
                        (Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe
                (subscriber);
    }


    /**
     * 班级加课
     *
     * @param grade_id   班级ID
     * @param week       星期几（1:星期一，2:星期二...7：星期天）
     * @param start_time 开始时间（12:00:00）
     * @param end_time
     * @param start_date 开始日期（2016-04-01）
     * @param end_date
     * @param subscriber
     */
    public void scheduleAddGrade(String grade_id, String week, String
            start_time, String end_time,
                                 String start_date, String end_date,
                                 Subscriber<WLXGetCodeBean> subscriber) {
        mMyService.scheduleChangeAddGrade(grade_id, week, start_time, end_time,
                start_date, end_date)
                .subscribeOn
                        (Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe
                (subscriber);
    }

    /**
     * 添加课程内容:文字
     *
     * @param schedule_id 课程ID
     * @param content     文字内容
     * @param subscriber
     */
    public void scheduleSetcontent(String schedule_id, String content,
                                   Subscriber<WLXGetCodeBean> subscriber) {
        mMyService.scheduleSetcontent(schedule_id, content).subscribeOn
                (Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe
                (subscriber);
    }

    /**
     * 上传图片文件(交作业)
     */
    public void uploadImages(Map<String, RequestBody> params, Subscriber<WLXUploadImagesBean>
            subscriber) {
        mMyService.uploadImages(params).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers
                .mainThread()).subscribe(subscriber);
    }

    /**
     * 上传视频文件(交作业)
     */
    public void uploadVideo(String resourceId, String resourceCode, String videoDuration,
                            MultipartBody.Part body, Subscriber<WLXUploadVideoBean> subscriber) {
        RequestBody resource_id = RequestBody.create(MediaType.parse("multipart/form-data"),
                resourceId);
        RequestBody resource_code = RequestBody.create(MediaType.parse("multipart/form-data"),
                resourceCode);
        RequestBody duration = RequestBody.create(MediaType.parse("multipart/form-data"),
                videoDuration);

        mMyService.uploadVideo(resource_id, resource_code, duration, body).subscribeOn(Schedulers
                .io()).observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 交视频作业前的homeworkAdd
     * 不携带schedule_id
     */
    public void homeworkAddForVideo(String student_id, String grade_id, String content, String
            content_code, Subscriber<WLXHomeworkAddBean> subscriber) {
        mMyService.homeworkAddForVideo(student_id, grade_id, content, content_code).subscribeOn
                (Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 交图片作业前的homeworkAdd
     */
    public void homeworkAddForImage(String student_id, String grade_id, String content, String
            content_code, String image_count, Subscriber<WLXHomeworkAddBean> subscriber) {
        mMyService.homeworkAddForImage(student_id, grade_id, content, content_code, image_count)
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe
                (subscriber);
    }

    /**
     * 结课
     *
     * @param grade_id
     * @param schedule_id
     * @param subscriber
     */
    public void courseFinished(String grade_id, String schedule_id,
                               Subscriber<WLXCourseFinishedBean>
                                       subscriber) {
        mMyService.courseFinished(grade_id, schedule_id).subscribeOn(Schedulers.io()).observeOn
                (AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 获取单个课程表信息
     *
     * @param schedule_id
     * @param subscriber
     */
    public void getSingleCourse(String schedule_id, Subscriber<WLXSingleCourseBean> subscriber) {
        mMyService.getSingleCourse(schedule_id).subscribeOn(Schedulers.io()).observeOn
                (AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 获取教师某个课程表课次的差评列表
     * @param schedule_id
     * @param subscriber
     */
    public void getBadList(String schedule_id, Subscriber<WLXScheduleScoreBean> subscriber) {
        mMyService.getBadList(schedule_id).subscribeOn(Schedulers.io()).observeOn
                (AndroidSchedulers.mainThread()).subscribe(subscriber);
    }

    /**
     * 课程变动
     * @param teacher_change_id
     * @param subscriber
     */
    public void getScheduleChange(String teacher_change_id,Subscriber<WLXScheduleChangeBean> subscriber){
        mMyService.getScheduleChange(teacher_change_id).subscribeOn(Schedulers.io()).observeOn
                (AndroidSchedulers.mainThread()).subscribe(subscriber);
    }
}
